package com.xbongbong.saas.service;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.dto.AddBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.AfterSaveVO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentDeleteBatchDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentEditAttrUpdateDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentInsertBatchDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentUpdateBatchDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentUpdateByBusinessRuleDTO;
import com.xbongbong.pro.payment.pojo.dto.RelationshipGetDTO;
import com.xbongbong.pro.payment.pojo.vo.PaymentDeleteBatchVO;
import com.xbongbong.pro.payment.pojo.vo.PaymentInsertBatchVO;
import com.xbongbong.pro.payment.pojo.vo.PaymentUpdateBatchVO;
import com.xbongbong.pro.payment.pojo.vo.PaymentUpdateByBusinessRuleVO;
import com.xbongbong.pro.payment.pojo.vo.PaymentVO;
import com.xbongbong.pro.payment.pojo.vo.RelationshipGetVO;
import com.xbongbong.pro.sheet.pojo.dto.SheetAmountDetailGetDTO;
import com.xbongbong.pro.sheet.pojo.dto.SheetDeleteHandleRelateDTO;
import com.xbongbong.pro.sheet.pojo.vo.HandleLinkInfoVO;
import com.xbongbong.pro.sheet.pojo.vo.SheetAmountDetailGetVO;
import com.xbongbong.pro.webdetail.pojo.dto.PaymentReturnDTO;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 回款业务
 *
 * @author feng.zheng
 * @version v1.0
 * @date 2019/1/18
 * @since v1.0
 */
public interface PaymentService {
    /**
     * 回款保存前saas特殊校验
     *
     * @param validateDataDTO saas特殊校验数据入参
     * @throws XbbException 业务异常
     * @author feng.zheng
     * @date 2019/1/18
     */
    void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException;

    /**
     * 回款保存后逻辑
     *
     * @param saasFormSaveDTO saas保存数据
     * @throws XbbException 业务异常
     * @author feng.zheng
     */
    AfterSaveVO afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException;



    /**
     * 回款
     * @author 吴峰
     * @date 2019/2/12 16:28
     * @param payMentDTO
     * @return com.xbongbong.pro.payment.pojo.vo.PaymentVO
     * @throws XbbException
     */
    FormDataAddVO pay(PaymentDTO payMentDTO) throws XbbException;
    /**
     * 批量判断编号是否重复，以及判断金额
     * @author 吴峰
     * @date 2019/2/14 11:09
     * @param payMentDTO
     * @return void
     * @throws XbbException
     */
    void validatePayment(PaymentDTO payMentDTO) throws XbbException;

    /**
     * 批量保存
     * @param paymentInsertBatchDTO
     * @param parentNew
     * @param creatorId 审批通过的合同可能不是当前登陆人创建的
     * @return 批量更新
     * @throws XbbException
     */
    PaymentInsertBatchVO insertBatch(PaymentInsertBatchDTO paymentInsertBatchDTO, Boolean parentNew, String creatorId) throws XbbException;


    /**
     * 批量删除
     * @author 吴峰
     * @date 2019/2/14 14:50
     * @param paymentDeleteBatchDTO
     * @return com.xbongbong.pro.payment.pojo.vo.PaymentDeleteBatchVO
     * @throws XbbException
     */
    PaymentDeleteBatchVO deleteBatch(PaymentDeleteBatchDTO paymentDeleteBatchDTO) throws XbbException;

    /**
     * 根据规则批量更新
     * @author 吴峰
     * @date 2019/2/22 11:18
     * @param paymentUpdateByBusinessRuleDTO
     * @return com.xbongbong.pro.payment.pojo.vo.UpdatePaymentByBusinessRuleVO
     * @throws XbbException 业务异常
     */
    PaymentUpdateByBusinessRuleVO updateFormDataByBusinessRule(PaymentUpdateByBusinessRuleDTO paymentUpdateByBusinessRuleDTO) throws XbbException;

    /**
     * 批量保存前置
     * @return
     * @throws XbbException
     * @param formDataSaveDTO
     */
    AddBatchDTO beforeSaveBatch(FormDataAddDTO formDataSaveDTO, boolean fromApproval) throws XbbException;

    /**
     * 判断回款的回款单是否有在审批中
     *
     * @param paymentId 应收款id
     * @param corpid    公司id
     * @return 创建时间： 2017-12-14 下午9:32:20
     * 修改时间：
     * @author chy
     */
    boolean paymentApproval(Long paymentId, String corpid);
    /**
     * 格式化移动端列表页
     *
     * @param formDataListDTO 用户
     * @param esEntities 业务实体集合
     * @param totalCount 总数
     * @return ListAppVO
     * @throws XbbException
     * @author long.rao
     * @date 2019-03-12 18:55
     */
    ListAppVO formatPaymentAppList(FormDataListDTO formDataListDTO, List<PaasFormDataEntityExt> esEntities, Integer totalCount) throws XbbException;

    /**
     * 关联新建时格式化解释
     *
     * @param handlerExplainInLinkItemDTO 入参
     * @throws XbbException 异常
     * @author feng.zheng
     * @date 2019-03-16 20:53
     */
    void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException;
    /**
     * 批量编辑某个字段
     * @author 吴峰
     * @date 2019/3/20 14:40
     * @param paymentEditAttrUpdateDTO
     * @return void
     * @throws XbbException 业务异常
     */
    void batchEditAttr(PaymentEditAttrUpdateDTO paymentEditAttrUpdateDTO) throws XbbException;

    /**
     * 资金管理应收款关联红冲回款单
     *
     * @param corpid 用户信息
     * @param paymentId 应收款id
     * @throws XbbException 异常
     * @return 红冲应收款
     */
    List<PaasFormDataEntityExt> getAssociationRedSheetList(String corpid, Long paymentId) throws XbbException;

    /**
     * 获取合同关联的付款计划
     *
     * @param corpid        公司id
     * @param contractId    合同id
     * @author GuoJun.HU
     * @since V1.0
     * @return List
     * @date 2019/4/11 17:40
     */
    List<PaasFormDataEntityExt> getPaymentEsDataListByContractId(String corpid, Long contractId) throws XbbException;
    /**
     * 获取客户关联的付款计划
     *
     * @param corpid        公司id
     * @param contractId    合同id
     * @author GuoJun.HU
     * @since V1.0
     * @return List
     * @date 2019/4/11 17:40
     */
    List<PaasFormDataEntityExt> getPaymentEsDataListByCustomerId(String corpid, Long contractId) throws XbbException;

    /**
     * 坏账还原
     *
     * @param paymentReturnDTO
     * @return
     * @throws XbbException
     */
    PaymentVO badDebtReturn(PaymentReturnDTO paymentReturnDTO) throws XbbException;

    PaymentUpdateBatchVO updateBatch(PaymentUpdateBatchDTO paymentUpdateBatchDTO) throws XbbException;

    /**
     * Description: 一致性同步客户
     * @param corpid
     * @param customerId
     * @param customerName
     * @author 魏荣杰
     * @date 2019/6/12 9:46
     * @since v1.0
     */
    void dataConsistencyUpdateCustomer(String corpid, Long customerId, String customerName) throws XbbException;
    /**
     * Description: 一致性同步合同
     * @param corpid
     * @param contractId
     * @param contractName
     * @author 魏荣杰
     * @date 2019/6/12 9:46
     * @since v1.0
     */
    void dataConsistencyUpdateContract(String corpid, Long contractId, String contractName) throws XbbException;

    /**
     * 更新回滚es
     * @param idIn
     * @param corpid
     * @throws XbbException
     */
    void updateRollback(Collection<Long> idIn, String corpid) throws XbbException;

    /**
     * 更新回滚es
     * @param payments es要回滚为的数据list
     * @param corpid
     * @throws XbbException
     */
    void updateRollback(List<PaymentEntityExt> payments, String corpid) throws XbbException;

    /**
     * 应收款导入
     * @param importFormDataDTO
     * @param titlePojoList
     * @param rowGroupPojo
     * @param fieldAttrList
     * @author chenshan
     * @date 2019-11-04 14:51
     * @return
     * @throws XbbException
     */
    FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException;

    /**
     * 通过合同ids获取其关联的应收款（未收、部分未收，或者已收、部分已收）
     * 当创建已核销、预收款核销、坏账时，要获取【未收、部分未收】的应收款，应收款不存在时，获取的是【合同未收金额】
     * 当红冲已核销、红冲预收款时，要获取原回款单redId关联的【已收、部分已收】的应收款，应收款不存在时，获取的是【合同已收金额】
     * 预收款、红冲预收款没有关联合同，不能调用该接口
     *
     * （1）如果合同下有应收款，则返回合同dataIdList对应的所有应收款list
     * （2）如果合同下无应收款，则只返回合同本身（及其未收金额或合同金额-红冲需要合同已收金额）
     * （3）如果redId不为空，则要获取该关联原始回款单的已红冲部分，从而算出可红冲金额
     * /detail/tab/payment/get
     * @param sumFlag true 只算总额（总未收或总已收），false 封装所有明细
     * @param sheetAmountDetailGetDTO
     * @return SheetAmountDetailGetVO
     * @throws XbbException
     * @author zcp
     * @date 19/11/12 012 10:30
     * @update 19/11/12 012 10:30
     * @since v1.0
     * @version v1.0
     */
    SheetAmountDetailGetVO paymentAmountDetailGet(boolean sumFlag, SheetAmountDetailGetDTO sheetAmountDetailGetDTO) throws XbbException;

    RelationshipGetVO getContractOrPaymentOrPaymentSheetInfo(RelationshipGetDTO relationshipGetDTO) throws XbbException;
    
    /**
     * 资金管理应收款关联红冲回款单
     *
     * @param corpid 用户信息
     * @param paymentId 应收款id
     * @param aloneList 回款关系类型(1:只有父类,2:父类,3:子类)
     * @throws XbbException 异常
     * @return 红冲应收款
     */
    List<PaasFormDataEntityExt> getAssociationRedSheetListByAlone(String corpid, Long paymentId, List<Integer> aloneList) throws XbbException;

    /**
     * 创建回款单时，处理应收款并封装要更新的结果：
     * （1）判断已收金额是否已经超过应收款内的未收金额，并把应收款的已收金额增加及更改其回款状态等
     * （2）处理回款金额、核销金额
     * （3）把红冲的回款金额置为负数
     * 已核销、预收款核销：已收金额增加，未收减少，限制回款金额小于计划的未收
     * @param paymentSheetTypeEnum 回款类型
     * @param sheetData 回款单（父级，级外层总的）data
     * @param corpid 公司id
     * @param paymentIdToAmount 计划id-该计划对应的回款金额
     * @param paymentIds 计划ids
     * @return com.xbongbong.pro.sheet.pojo.vo.HandleLinkInfoVO
     * @throws XbbException
     * @author zcp
     * @date 19/11/23 023 15:41
     * @update 19/11/23 023 15:41
     * @update 20/10/19
     * @since v1.0
     * @version 资金3.0 by zcp 更改返回值为HandleLinkInfoVO，用以处理子回款单的modelType（子回款单的modelType为其关联的应收款的类型，父回款单直接使用当前启用的模式）；及回滚es时，把原数据库数据同步到es内
     */
    HandleLinkInfoVO handlePayment(PaymentSheetTypeEnum paymentSheetTypeEnum, JSONObject sheetData, String corpid, Map<Long, Double> paymentIdToAmount, Set<Long> paymentIds) throws XbbException;

    /**
     * 删除回款单时，同步更新应收款
     * @param corpid 公司id
     * @param errorTypeSet 不允许删除类型
     * @param errorDataSet 不允许删除数据
     * @param allDelIdList 所有要删除的回款单id集合（因为重置更新应收款的时间时，需要查询除allDelIdList之外的回款单）
     * @param sheetDeleteHandleRelateDTO 删除/批量删除回款单，更新其关联业务（客户、合同、应收款）dto
     * @return java.util.List<com.xbongbong.pro.domain.entity.UpdateDataEntity>
     * @throws XbbException
     * @author zcp
     * @date 19/12/6 006 21:21
     * @update 19/12/6 006 21:21
     * @since v1.0
     * @version v1.0
     */
    List<UpdateDataEntity> updatePayment4Del(String corpid, Set<String> errorTypeSet, Set<String> errorDataSet, Collection<Long> allDelIdList, SheetDeleteHandleRelateDTO sheetDeleteHandleRelateDTO) throws XbbException;

    /**
     * 处理应收款的回款状态（坏账优先级最高）
     * @param planAmount 计划金额
     * @param unAmount 未收金额
     * @param badAmount 坏账金额
     * @param redAmount 红冲应收款金额（直接使用数据库内存储的值，即负数格式）
     * @return java.lang.String
     * @author zcp
     * @date 19/12/6 006 21:04
     * @update 19/12/6 006 21:04
     * @since v1.0
     * @version v1.0
     */
    String handleStatus(Double planAmount, Double unAmount, Double badAmount, Double redAmount);
    
    /**
     * 获取所有的红冲应收款
     * @param formDataListDTO
     * @return
     * @throws XbbException
     * @author chenshan
     * @data 2019/12/13 11:21
     */
    PaasFormDataEsListVO getPaymentList(FormDataListDTO formDataListDTO) throws XbbException;

    void updateBatchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, Boolean addOrDelete) throws XbbException;


    /**
     * 获取来源单据的所有应收款
     * @param corpid
     * @param indexTypeEnum
     * @param sourceId
     * @return
     * @throws XbbException
     */
    Map<Long,Double> getReceivablesAmount(String corpid, IndexTypeEnum indexTypeEnum, List<Long> sourceId)throws XbbException;

    /**
     * 查询应收款，并判断应收款是否可以删除
     * @param corpid
     * @param xbbRefTypeEnum
     * @param dataIdList
     * @return java.util.List<com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt>
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    List<PaasFormDataEntityExt> checkCanDelPayment(String corpid, XbbRefTypeEnum xbbRefTypeEnum, List<Long> dataIdList) throws XbbException;

    /**
     *
     * @param corpid
     * @param sourceRefType XbbRefTypeEnum对应的code
     * @param sourceId
     * @return
     * @throws XbbException
     * @update by zcp 支持出库单等查询
     */
   List<PaasFormDataEntityExt> getReceivablesBySourceIdIn(String corpid, Integer sourceRefType, List<Long> sourceId)throws XbbException;

    /**
     *
     * @param corpid
     * @param indexTypeEnum
     * @param receivablesOriginIdIn
     * @return
     * @throws XbbException
     */
   List<PaasFormDataEntityExt> getEntityByReceivablesOriginIdIn(String corpid,IndexTypeEnum indexTypeEnum,List<Long> receivablesOriginIdIn) throws XbbException;

    void afterSaveForWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException;

    void afterSaveForUpdateWorkflow(SaasFormSaveDTO saasFormSaveDTO);

    /**
     * 上游销项发票编号改了，下游应收款中来源单据中的编号也会同步修改，这种在发票产生应收的模式下会存在这种情况
     *
     * @param corpid
     * @param dataId
     * @param invoiceSerialNo
     */
    void dataConsistencyUpdateInvoice(String corpid, Long dataId, String invoiceSerialNo) throws XbbException;

    /**
     * 游销项发票编号改了，下游应收款中来源单据中的编号也会同步修改，这种在出库产生应收的模式下会存在这种情况
     *
     * @param corpid
     * @param dataId
     * @param contractOutStockSerialNo
     */
    void dataConsistencyUpdateContractOutStock(String corpid, Long dataId, String contractOutStockSerialNo) throws XbbException;
}
